<?php


namespace App\Imports;

use App\Exceptions\ApiException;
use App\Services\CommonService;
use App\Services\ProjectClassifyService;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithColumnLimit;
use Maatwebsite\Excel\Concerns\WithLimit;
use Maatwebsite\Excel\Concerns\WithStartRow;

/**
 * Class BookTitleImport
 * @package App\Imports
 * 适用于 29号文件
 */
class BookTitleImport8 implements ToModel, WithChunkReading, WithStartRow, WithColumnLimit, WithBatchInserts, WithLimit
{
    protected $partCompanyId;
    protected $chunkSize;
    protected $startRow;
    protected $endColumn;
    protected $batchSize;
    protected $baseArchivesNo;
    protected $bookTitleInstance;
    protected $importDetailKey;
    protected $projectClassifyRedisKey;
    protected $importDetail;
    protected $allImportArchiveNosRedisKey; //导入的案卷全部单位工程
    protected $canImportArchiveNosRedisKey; //有效导入的案卷涉及的单位工程

    public function __construct($partCompanyId, $importDetailKey)
    {
        $this->importDetailKey = $importDetailKey;
        $this->limit          = 8000; //只读取前8000行
        $this->chunkSize      = 100;  //将数据拆成小块读取
        $this->startRow       = 2;    //从第几行开始
        $this->endColumn      = 'O';  //指定到那一列为止
        $this->batchSize      = 100;  //批量写入的数据大小
        $this->partCompanyId  = $partCompanyId; //参建单位
        $this->allImportArchiveNosRedisKey    = $importDetailKey . ":AllImportArchiveNos";
        $this->canImportArchiveNosRedisKey    = $importDetailKey . ":CanImportArchiveNos";
    }

    /**
     * 导入数据
     */
    public function model(array $row)
    {
        $this->checkFormat($row); //第一步，核对格式

        $allImportArchiveNosRedisKey = $this->allImportArchiveNosRedisKey;
        $canImportArchiveNosRedisKey = $this->canImportArchiveNosRedisKey;

        if (is_numeric($row[0]) && trim($row[1])) { //is_numeric($row[0]) 因为中间可能会出现【路基】独自占领一行需排除
            $archivesNo = format_archives_no(trim($row[1]));
            $projectClassify = ProjectClassifyService::getProjectClassifyArrInfo($this->partCompanyId, $archivesNo, $allImportArchiveNosRedisKey, $canImportArchiveNosRedisKey);  //和项目分类数据进行比对，判断往哪个里面写入
            if ($projectClassify) {
                $bookTitleInstance = CommonService::getBookTitleInstance($this->partCompanyId, $projectClassify['id']);
                $bookTitleInstance->updateOrCreate(
                    [ //查询条件
                        'part_company_id'     => $this->partCompanyId,     //参建单位
                        'project_classify_id' => $projectClassify['id'],
                        'archives_no'         => $archivesNo,
                    ],
                    [
                        'serial_no'           => get_archives_serial_no($archivesNo),//序号
                        'title'               => format_str($row[2]),      //名称
                        'blueprint'           => to_int($row[3]),          //蓝图
                        'base_map'            => to_int($row[4]),          //底图
                        'volume'              => $row[5] ?: 1,             //册
                        'page_num'            => to_int($row[6]),          //页数
                        'years'               => format_str($row[7]),      //所属年代
                        'store_period'        => format_str($row[8]),      //保管期限
                        'secret_level'        => format_str($row[9]),      //保密程度
                        'cabin_no'            => format_str($row[10]),     //柜号
                        'remark'              => format_str($row[11]),     //备注
                        'mixed_no'            => format_str($row[12]),     //互见号
                        'construction_miles'  => format_str($row[13]),     //建设里程
                        'completed_miles'     => format_str($row[14]),     //完成里程
                        'start_date'          => '',                       //开始日期
                        'end_date'            => '',                       //结束日期
                        'created_at'          => now(),
                        'updated_at'          => now(),
                        'creator_id'          => user_id(),
                        'is_need_check'       => 1, //如果案卷进行了修改，要重新检查
                    ]);
                redis()->hincrby($this->importDetailKey, $projectClassify['title'], 1); //使用 redis()->hset(); //hash对指定的单位工程导入案卷数量数值进行加 操作
            }
        }
    }

    /**
     * 检查格式是否正确，判断列的属性汉字
     * @author: lxk
     * @date: 2023/6/3 15:18
     */
    public function checkFormat($row)
    {
        if (format_table_label($row[0]) == '顺号' || format_table_label($row[0]) == '序号') {
            if (format_table_label($row[1]) != '档案号'
                || format_table_label($row[2]) != '名称'
                || format_table_label($row[3]) != '种类'
                || format_table_label($row[5]) != '数量'
                || format_table_label($row[7]) != '所属年代'
                || format_table_label($row[8]) != '保管期限'
                || format_table_label($row[9]) != '机密程度'
                || format_table_label($row[10]) != '柜号'
                || format_table_label($row[11]) != '备注'
                || format_table_label($row[12]) != '互见号'
                || format_table_label($row[13]) != '里程'
            ) {
                throw new ApiException("案卷格式错误！列属性名必须和模板完全一致，请下载模板，核对数据列【A~I】");
            }
        }
    }

    /**
     * 将数据拆成小块进行导入，减小内存占用
     *
     * @return int
     */
    public function chunkSize(): int
    {
        return $this->chunkSize;
    }

    /**
     * 直接过滤表头，第一块数据含表头
     *
     * @return int
     */
    public function startRow(): int
    {
        return $this->startRow;
    }

    /**
     * 指定到那一列为止，G代表读取到G列就不再读取
     *
     * @return string
     */
    public function endColumn(): string
    {
        return $this->endColumn;
    }

    /**
     * 批量写入的数据大小
     *
     * @return int
     */
    public function batchSize(): int
    {
        return $this->batchSize;
    }

    public function limit(): int
    {
        return $this->limit;
    }

}
